package storage

import (
	"gin-base/common/utils"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"strconv"
	"time"
)

const BaseSavePath = "public/"
const SavePath = "upload/"
const SavePathTmp = "upload_tmp/"
const RangeSize = 8

func init() {

}

func SaveToFile(r *http.Request, fromfile, saveFileName string) (string, error) {
	file, _, err := r.FormFile(fromfile)
	defer file.Close()

	if err != nil {
		return "", err
	}

	//获取存储目录
	savePath := getSavePath(true, "")
	//创建目录
	os.MkdirAll(savePath, 0666)

	//拼装最后的文件名
	saveFileName = getSaveName(savePath, saveFileName)

	//保存到文件
	error := Save(file, saveFileName)
	if error != nil {
		saveFileName = ""
	}

	return saveFileName, error
}

func Save(file multipart.File, tofile string) error {
	defer file.Close()
	f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		return err
	}
	defer f.Close()
	io.Copy(f, file)
	return nil
}

func getSavePath(isTmp bool, namespace string) string {
	path := BaseSavePath
	if isTmp {
		path += SavePathTmp
	} else {
		path += SavePath
	}

	if namespace != "" {
		path = path + namespace + "/"
	}

	// 依据 年 月 日
	path = path + strconv.Itoa(time.Now().Year()) + "/" + strconv.Itoa(int(time.Now().Month())) + "/" + strconv.Itoa(time.Now().Day()) + "/"

	return path
}

func getSaveName(path string, fileName string) string {
	saveFileName := path + utils.Srand(RangeSize, 3) + "==" + fileName

	//判断文件是否存在
	_, exist := os.Stat(saveFileName)
	if exist != nil {
		return saveFileName
	} else {
		return getSaveName(path, fileName)
	}
}

//将临时文件迁移到正式目录
func ConfirmTmpFile(uri string) (string, error) {
	tmpPath := BaseSavePath + SavePathTmp
	if tmpPath == string([]rune(uri)[:len(tmpPath)]) {
		//判断文件是否存在
		fileInfo, err := os.Stat(uri)
		if err != nil {
			return uri, err
		}
		fileName := fileInfo.Name()

		newUri := BaseSavePath + SavePath + string([]rune(uri)[len(tmpPath):])
		//创建目录
		newPath := string([]rune(newUri)[:len(newUri)-len(fileName)])
		os.MkdirAll(newPath, 0666)

		//迁移文件
		err = os.Rename(uri, newUri)

		if err != nil {
			return uri, err
		}

		return newUri, nil
	}

	return uri, nil
}

func DeleteFile(uri string) bool {
	err := os.Remove(uri)
	if err != nil {
		if isExist(uri) {
			return false
		} else {
			return true
		}
	} else {

		return true
	}
}

func isExist(uri string) bool {
	//判断文件是否存在
	_, err := os.Stat(uri)
	if err != nil {
		return false
	} else {
		return true
	}
}
